package com.jsmile.cloud.authc.web.security.provider;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.google.common.collect.Maps;
import com.jsmile.cloud.authc.api.enums.SmsTypeEnum;
import com.jsmile.cloud.authc.api.exception.AuthcException;
import com.jsmile.cloud.authc.web.config.AuthcConfig;
import com.jsmile.cloud.authc.web.security.JsmileUserService;
import com.jsmile.cloud.msgcenter.api.feign.MsgServiceApi;
import com.jsmile.cloud.msgcenter.api.to.SmsTo;
import com.jsmile.mail.security.security.JsmileUser;
import com.jsmile.mall.api.JSmileResult;
import com.jsmile.mall.api.enums.JSmileCodeEnum;
import com.jsmile.mall.api.enums.LoginTypeEnum;
import com.jsmile.mall.cache.kit.SpringKit;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SsoAuthProvider implements AuthenticationProvider {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JsmileUserService jsmileUserService;
    @Autowired
    private AuthcConfig msgBizConfig;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Map<String, String> details = (Map)authentication.getDetails();
        String username = authentication.getName();
        String code = details.get("code");// 验证码
        JsmileUser userDetails = (JsmileUser)jsmileUserService.loadUserByUsername(username);
        if (LoginTypeEnum.MOBILE.getValue().equalsIgnoreCase(details.get("login_type"))) {// 验证码认证
            verifyCode(code, username);
        }
        if (LoginTypeEnum.USERNAME.getValue().equalsIgnoreCase(details.get("login_type"))) {// 密码认证
            if (!passwordEncoder.matches((String)authentication.getCredentials(), userDetails.getPassword())) {
                throw new AuthcException(JSmileCodeEnum.ACCOUNT_ERROR);
            }
        }
        return new UsernamePasswordAuthenticationToken(userDetails, authentication.getCredentials(), userDetails.getAuthorities());
    }

    /**
     * 验证码验证
     */
    private void verifyCode(String code, String phone) {
        if (msgBizConfig.hasVerifyPhone(phone)) {
            SmsTo smsTo = new SmsTo();
            smsTo.setPhone(phone);
            Map<String, String> param = Maps.newHashMap();
            param.put("code", code);
            smsTo.setSmsType(SmsTypeEnum.LOGIN.getValue());
            smsTo.setSmsParams(param);
            JSmileResult result = SpringKit.getBean(MsgServiceApi.class).verifyCode(smsTo);
            if (!result.getResSuccess()) {
                throw new AuthcException(result.getResCode(), result.getResMsg(), null);
            }
        }
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
